/**
 * Created by cuppi on 2017/7/31.
 */


const NormalDistributionC = 1/Math.sqrt(2*Math.PI);
class RandomManager {
    /**
     * 获取均匀分布的随机变量
     * 概率密度函数为 y = C
     * @return 连续型随机变量
     */
    static uniformDistribution(min, max){
        let random = Math.random(); // [0.0. 1.0)
        let space = max - min;
        return min + space*random;
    }

    /**
     * 获取标准正态分布的随机变量
     * @param min 最小值
     * @param max 最大值
     * @return 连续型随机变量
     */
    static standardNormalDistribution(min, max){
        let x, y, maybe;
        do{
            x = RandomManager.uniformDistribution(min, max);
            y = RandomManager.standardNormalDistributionFunction(x);
            maybe = RandomManager.uniformDistribution(0, NormalDistributionC);
        } while(maybe > y);
        return x;
    }

    /**
     * 获取正态分布的随机变量
     * @param miu   期望
     * @param sigma 均值
     * @param min   最小值
     * @param max   最大值
     * @return 连续型随机变量
     */
    static normalDistribution(miu, sigma, min, max){
        let x, y, maybe;
        do{
            x = RandomManager.uniformDistribution(min, max);
            y = RandomManager.standardNormalDistributionFunction(x);
            maybe = RandomManager.uniformDistribution(0, RandomManager.normalDistributionFunction(miu, sigma, 0));
        } while(maybe > y);
        return x;
    }

    /**
     * 标准正态分布函数
     * @param x x坐标轴N
     * @return  x坐标轴对应的值
     */
    static standardNormalDistributionFunction(x){
        return NormalDistributionC * Math.pow(Math.E, -x*x*0.5);
    }

    /**
     * 正态分布函数
     * @param miu   期望
     * @param sigma 均值
     * @param x     x坐标轴
     * @return      x坐标轴对应的值
     */
    static normalDistributionFunction(miu, sigma, x){
        return NormalDistributionC*(1/sigma) * Math.pow(Math.E, -(x - miu)*(x - miu)*(1/(2*sigma*sigma)));
    }
}

module.exports = RandomManager;